package com.yj.springbootstudy.mulThread.imooc;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用condition 实现生产者消费者模型
 *
 *
 * 创建一个工厂类 ProductFactory，该类包含两个方法，produce 生产方法和 consume 消费方法（未改变）；
 * 对于 produce 方法，当没有库存或者库存达到 10 时，停止生产。为了更便于观察结果，每生产一个产品，sleep 3000 毫秒（5000 变 3000，调用地址也改变了，具体看代码）；
 * 对于 consume 方法，只要有库存就进行消费。为了更便于观察结果，每消费一个产品，sleep 5000 毫秒（sleep 调用地址改变了，具体看代码）；
 * 库存使用 LinkedList 进行实现，此时 LinkedList 即共享数据内存（未改变）；
 * 创建一个 Producer 生产者类，用于调用 ProductFactory 的 produce 方法。生产过程中，要对每个产品从 0 开始进行编号 (新增 sleep 3000ms)；
 * 创建一个 Consumer 消费者类，用于调用 ProductFactory 的 consume 方法 (新增 sleep 5000ms)；
 * 创建一个测试类，main 函数中创建 2 个生产者和 3 个消费者，运行程序进行结果观察（未改变）。
 *
 *
 */
public class Demo06 {


    public static void main(String[] args) {
        ProductFactory productFactory = new ProductFactory();
        new Thread(()->{
            int i = 0;
            while (true){
                productFactory.produce(i++ + "");
            }
        }).start();

        new Thread(()->{
            int i = 0;
            while (true){
                productFactory.consume();
            }
        }).start();
    }

}

class ProductFactory{

    private LinkedList linkedList = new LinkedList();
    private int capacity = 10;
    private Lock lock = new ReentrantLock();
    private Condition conditionP = lock.newCondition();
    private Condition conditionC = lock.newCondition();

    public void produce(String name){
        try {
            lock.lock();

            while (linkedList.size() == capacity){
                conditionP.await();
            }
            linkedList.add(name);
            conditionC.signal();
            System.out.println("生产者生产了一件商品:"+name);
            Thread.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void consume(){
        try {
            lock.lock();
            while (linkedList.size() == 0){
                System.out.println("当前队列为空！通知生产者生产！");
                conditionC.await();
            }
            String name  = (String) linkedList.removeFirst();
            System.out.println("消费者消费了一件商品："+name);
            conditionP.signal();
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }
    }
}

